package colour;

/**
 * This is class which is used for storing the information of the pixels as
 * GRB.Providing some operation for getting and setting RGB.Store the RGB as
 * Byte format to save the space In java, Byte is signed and we have deal with
 * the upper bit to make sure the number is correct Two construtors can receive
 * Byte and Integer
 * 
 * @author Yuting Wu
 * @author Kan Lin
 * @author Bing Dong
 * @version 1.0
 * 
 * @param red
 *            the red vaule of a colour
 * 
 * @param green
 *            the green vaule of a colour
 * 
 * @param blue
 *            the blue vaule of a colour
 * 
 * @param RGB
 *            vector for the RGB value, nheight*height+width is used to locate
 *            the element
 * 
 * @param colour
 *            a single data type of colour component
 * 
 */
public class Colour {

	private byte red = -1;
	private byte green = -1;
	private byte blue = -1;
	private boolean empty = true;

	/**
	 * @return whether Color is empty
	 */
	public boolean isEmpty() {
		return empty;
	}

	/**
	 * Constructor for the class Colour. Assign the necessary value for the
	 * Colour Object. The param is byte.
	 * 
	 * @param r
	 *            red value of a colour for the new Colour Object
	 * @param g
	 *            green value of a colour for the new Colour Object
	 * @param b
	 *            blue value of a colour for the new Colour Object
	 */
	public Colour(final byte nRed, final byte nGreen, final byte nBlue) {
		red = nRed;
		green = nGreen;
		blue = nBlue;
		this.empty = false;
	}

	/**
	 * Constructor for the integer param
	 * 
	 * @param r
	 *            the red colour of a colour
	 * @param g
	 *            the green colour of a colour
	 * @param b
	 *            the blue colour of a colour
	 */
	public Colour(final int nRed, final int nGreen, final int nBlue) {
		// bit shift to change int to byte
		red = (byte) ((nRed << 24) >> 24);
		green = (byte) ((nGreen << 24) >> 24);
		blue = (byte) ((nBlue << 24) >> 24);
		this.empty = false;
	}

	/**
	 * This method translate signed Byte into Integer
	 * 
	 * @return a array contain a RGB as int[]
	 */
	public int[] getRGB() {
		// clearing the bits in the postion higher than the 8th.
		// transform the signed byte to integer with result of the unsigned
		// type.
		int[] rgb = new int[] { (int) (0x000000FF & red),
				(int) (0x000000FF & green), (int) (0x000000FF & (blue)) };
		return rgb;
	}

	/**
	 * A method which executes multiply operation.
	 * 
	 * @param value
	 * @return a RGB which is multiplied by input value
	 */
	public Colour multiply(final double value) {
		int nRed = (int) (0x000000FF & red);
		int nGreen = (int) (0x000000FF & green);
		int nBlue = (int) (0x000000FF & blue);

		nRed = (int) (nRed * value);

		if (nRed > 255) {
			nRed = 255;
		}

		nGreen = (int) (nGreen * value);

		if (nGreen > 255) {
			nGreen = 255;
		}

		nBlue = (int) (nBlue * value);

		if (nBlue > 255) {
			nBlue = 255;
		}

		final Colour result = new Colour(nRed, nGreen, nBlue);

		return result;
	}

	/**
	 * A method which executes add operation.
	 * 
	 * @param color
	 *            input color which will be added
	 * @return result of add operation
	 */
	public Colour add(final Colour color) {
		int nRed = (int) (0x000000FF & red);
		int nGreen = (int) (0x000000FF & green);
		int nBlue = (int) (0x000000FF & blue);

		nRed = (int) (nRed + color.getRGB()[0]);

		if (nRed > 255) {
			nRed = 255;
		}

		nGreen = (int) (nGreen + color.getRGB()[1]);

		if (nGreen > 255) {
			nGreen = 255;
		}

		nBlue = (int) (nBlue + color.getRGB()[2]);

		if (nBlue > 255) {
			nBlue = 255;
		}

		return new Colour(nRed, nGreen, nBlue);
	}

	

}
